﻿using System.Collections.Generic;
using System.Windows;

namespace XmlStudio.ViewModel {
    /// <summary>
    /// Layout manager from Graph#.
    /// </summary>
    public class LayoutManager : DependencyObject {
        private static LayoutManager instance;

        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <value>The instance.</value>
        public static LayoutManager Instance {
            get {
                if(instance == null)
                    instance = new LayoutManager();

                return instance;
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LayoutManager"/> class.
        /// </summary>
        protected LayoutManager() {

        }

        /// <summary>
        /// Continues the layout.
        /// </summary>
        public void ContinueLayout() {
            foreach(var layout in GraphLayouts) {
                layout.ContinueLayout();
            }
        }

        /// <summary>
        /// Relayouts this instance.
        /// </summary>
        public void Relayout() {
            foreach(var layout in GraphLayouts) {
                layout.Relayout();
            }
        }

        protected readonly HashSet<XmlGraphLayout> GraphLayouts = new HashSet<XmlGraphLayout>();

        public static readonly DependencyProperty ManagedLayoutProperty =
            DependencyProperty.RegisterAttached("ManagedLayout", typeof(bool), typeof(LayoutManager), new PropertyMetadata(false, ManagedLayout_PropertyChanged));

        /// <summary>
        /// Gets the managed layout.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <returns></returns>
        [AttachedPropertyBrowsableForChildren]
        public static bool GetManagedLayout(DependencyObject obj) {
            return (bool)obj.GetValue(ManagedLayoutProperty);
        }

        /// <summary>
        /// Sets the managed layout.
        /// </summary>
        /// <param name="obj">The obj.</param>
        /// <param name="value">if set to <c>true</c> [value].</param>
        public static void SetManagedLayout(DependencyObject obj, bool value) {
            obj.SetValue(ManagedLayoutProperty, value);
        }

        protected static void ManagedLayout_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
            var graphLayout = obj as XmlGraphLayout;
            if(graphLayout == null)
                return;

            if((bool)e.NewValue) {
                //the layout became managed
                Instance.GraphLayouts.Add(graphLayout);
                // graphLayout.Unloaded += GraphLayout_Unloaded; // workaround for refresh issue
            } else if((bool)e.OldValue && (((bool)e.NewValue) == false) && Instance.GraphLayouts.Contains(graphLayout)) {
                //the layout became unmanaged
                Instance.GraphLayouts.Remove(graphLayout);
                // graphLayout.Unloaded -= GraphLayout_Unloaded; // workaround for refresh issue
            }
        }

        /*
                private static void GraphLayout_Unloaded(object s, RoutedEventArgs args)
                {
                    if (s is XmlGraphLayout)
                        Instance.GraphLayouts.Remove(s as XmlGraphLayout);
                }
        */
    }
}
